home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pctchnqs / 1990 / number5 / l6.asm < prev    next >
Assembly Source File  |  1990-09-30  |  3KB  |  68 lines

  1. ; Alternative optimized assembly language version of FindIDAverage
  2. ; that requires data organized as two arrays within each block rather
  3. ; than as an array of two-value element structures. This allows the
  4. ; use of REP SCASW for ID searching.
  5.  
  6. SearchedForID   equ     4       ;passed parameter offsets in the
  7. BlockPointer    equ     6       ; stack frame (skip over pushed BP
  8.                                 ; and the return address)
  9. NextBlock       equ     0       ;field offsets in struct BlockHeader
  10. BlockCount      equ     2
  11. BLOCK_HEADER_SIZE equ   4       ;# of bytes in struct BlockHeader
  12.  
  13.         .model  small   
  14.         .code
  15.         public  _FindIDAverage2
  16. _FindIDAverage2 proc    near
  17.         push    bp              ;save caller's stack frame
  18.         mov     bp,sp           ;point to our stack frame
  19.         push    di              ;preserve C register variables
  20.         push    si
  21.         mov     di,ds           ;prepare for SCASW
  22.         mov     es,di
  23.         cld
  24.         mov     si,[bp+BlockPointer]    ;pointer to first block
  25.         mov     ax,[bp+SearchedForID]   ;ID we're looking for
  26.         sub     dx,dx           ;IDMatchSum = 0
  27.         mov     bp,dx           ;IDMatchCount = 0
  28.                                 ;***stack frame no longer available***
  29. ; Search through all of the linked blocks until the last block
  30. ; (marked with a NULL pointer to the next block) has been searched.
  31. BlockLoop:
  32. ; Search through all the DataElement entries within this block
  33. ; and accumulate data from all that match the desired ID.
  34.         mov     cx,[si+BlockCount]
  35.         jcxz    DoNextBlock     ;skip this block if there's no data
  36.                                 ; to search through
  37.         mov     bx,cx           ;we'll use BX to point to the
  38.         shl     bx,1            ; corresponding value entry in the
  39.                                 ; case of an ID match (BX is the
  40.                                 ; length in bytes of the ID array)
  41. ; Point to the first DataElement entry within this block.
  42.         lea     di,[si+BLOCK_HEADER_SIZE]
  43. IntraBlockLoop:
  44.         repnz   scasw           ;search for the ID
  45.         jnz     DoNextBlock     ;no match, the block is done
  46.         inc     bp              ;we have a match; IDMatchCount++;
  47.         add     dx,[di+bx-2]    ;IDMatchSum += DataPointer->Value;
  48.                                 ; (SCASW has advanced DI 2 bytes)
  49.         and     cx,cx           ;is there more data to search through?
  50.         jnz     IntraBlockLoop  ;yes
  51. ; Point to the next block and continue if that pointer isn't NULL.
  52. DoNextBlock:
  53.         mov     si,[si+NextBlock] ;get pointer to the next block
  54.         and     si,si           ;is it a NULL pointer?
  55.         jnz     BlockLoop       ;no, continue
  56. ; Calculate the average of all matches.
  57.         sub     ax,ax           ;assume we found no matches
  58.         and     bp,bp
  59.         jz      Done            ;we didn't find any matches, return 0
  60.         xchg    ax,dx           ;prepare for division
  61.         div     bp              ;return IDMatchSum / IDMatchCount
  62. Done:   pop     si              ;restore C register variables
  63.         pop     di
  64.         pop     bp              ;restore caller's stack frame
  65.         ret     
  66. _FindIDAverage2 ENDP
  67.         end
  68.